#!/bin/bash 
# add -x to debug

# the script will do the following:
# Auth to ZM API
# Get list of monitors with events in the last eleven minutes
# Restart any monitors that have 0 events in the last eleven minutes (any that don't appear in the list)
# requires logger (but can edit that out if not available), thats it.
# tested in devuan jessie


# NOTE: this will work with any cameras that record constantly, such as Record, Mocord.
# For any cameras that don't record events constantly, you'd have to lengthen the delay in the curl request
# It will still work, but it won't report a dropout as quickly. This isn't as much a concern in my setup and is not addressed yet.

# See instructions for cronjobs to add.


# find in the logs by searching for zmrestart, if you have logger installed

# change these variables for your setup
USERNAME="username"
PASSWORD="username"

# requires optional email setup on ZM. See wiki.zoneminder.com/SMS_Notifications
# comment out email in script if not using
EMAIL="email@address.com"

# function for the camera. If you have varying functions you
# will need to implement on your own
# I use runstates that reset everything every so often, so I'm just going to mocord/record any dropped cameras
# Case sensitive
FUNCTION="Mocord"

# script must have write access to these files, and directory which its run in
EVENTSFILE="/root/lasthourevents.log"
PARSEFILE="/root/lasthour2.log"
SERVERLOCATION="localhost"
COOKIE="/root/cookies.txt"
EMAILCOUNTER="/root/emailcounter.dat"

# we look for these IDs in the json results, and in this order. Edit to include your monitor numbers.
# omit monitors that you don't want searched for. Do not need to be in order.
# Find monitorIds in Mysql: use zm; select ID from Monitors;
CAMERAMONITORIDSTOCHECK=(1 2 3 4 5 6)
ARRAYLENGTH=${#CAMERAMONITORIDSTOCHECK[@]}

# dont need to change these
MONITORNUMBER=0
EMAILNUM=0;


# auth to zm
curl -d "username=$USERNAME&password=$PASSWORD&action=login&view=console" -c $COOKIE  $SERVERLOCATION/zm/index.php

# this returns number of events in the 15 minutes for all cameras that have events. if events are zero, nothing is returned for
# that monitor. I found 15 minutes to be the lowest time I could set without false alerts.

# can be adjusted. 1%20hour is equivalent to 1 hour (%20 is space..?). can also use minutes, days, etc.
# see: https://github.com/ZoneMinder/ZoneMinder/blob/master/web/api/app/Controller/EventsController.php#L259
curl -b $COOKIE "$SERVERLOCATION/zm/api/events/consoleEvents/15%20minute.json" -o $EVENTSFILE



# get all events
# for cut you can use '"' or  \"
# cut is neat
# For 1.29
grep -Po ^[^:]*  $EVENTSFILE | tail -n +3 | head -n -2 | cut -d \" -f 2 > $PARSEFILE

# For 1.30.4
#cat $EVENTSFILE  | cut -d \{ -f3 |  rev | cut -c 3- | rev | sed 's/,/\'$'\n/g'|   cut -d \" -f2 > $PARSEFILE

# rev|cut -c 3- | rev     - this will delete last three characters
# sed 's/,/\'$'\n/g'      - this will replace commas with newlines

for (( i=0; i<$ARRAYLENGTH; i++ ))
do
	grep  ^${CAMERAMONITORIDSTOCHECK[i]}$ $PARSEFILE

		# if not found, grep returns error / value of one
		# if return code is error/false
		# if $? == 1
		if [ $? == 1 ]
			then
			# restartcamera

			echo "RESTARTING CAMERA ${CAMERAMONITORIDSTOCHECK[i]}"


			curl -b $COOKIE -XPOST $SERVERLOCATION/zm/api/monitors/${CAMERAMONITORIDSTOCHECK[i]}.json -d "Monitor[Function]=None&Monitor[Enabled]=0"

	                logger "camera ${CAMERAMONITORIDSTOCHECK[i]} has been disabled by zmrestart bashloop."

        	        # wait a little while (say 30 seconds)
			# required
                	sleep 30

	                # enable designated camera again
        	        curl -b $COOKIE -XPOST $SERVERLOCATION/zm/api/monitors/${CAMERAMONITORIDSTOCHECK[i]}.json -d "Monitor[Function]=$FUNCTION&Monitor[Enabled]=1"

	                logger "camera ${CAMERAMONITORIDSTOCHECK[i]} has been enabled by the zmrestart bashloop."



			# we only want a max of 7 alarms a day. After that, we block all alerts. If 7 of the same camera is reached, you can imagine that
			# the camera has some underlying problem, and must be looked at. Such as the PSU being disconnected.
			# run a cron job to blank $EMAILCOUNTER once a day.

			EMAILNUM=$(wc -l $EMAILCOUNTER | cut -c 1)
			if [ $EMAILNUM -lt 7 ]
				then

				echo "${CAMERAMONITORIDSTOCHECK[i]} restarted." >> $EMAILCOUNTER

        		        # email notification (if email is setup)
                		echo "${CAMERAMONITORIDSTOCHECK[i]} has been restart on a zm server" | mutt -s "zmcamerarestart mon ${CAMERAMONITORIDSTOCHECK[i]}." $EMAIL
				fi



		fi


done

logger "zmrestart bash loop has completed."
